package com.dlc.shop.poly.common.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.linchuang.seneca.constants.PolyConstants;
import com.linchuang.seneca.constants.PolyMallConstants;
import com.linchuang.seneca.enums.PolyErrorCodeEnum;
import com.linchuang.seneca.exception.PolyMallException;
import com.linchuang.seneca.request.PolyMallCommonRequest;
import com.dlc.shop.common.poly.PolyMp;
import com.dlc.shop.config.ShopConfig;
import com.dlc.shop.poly.common.service.PolyMallService;
import com.linchuang.seneca.request.PolyMallCommonGetOrderTraceRequest;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@AllArgsConstructor
abstract class BasePolyMallServiceImpl implements PolyMallService {

    private final ShopConfig shopConfig;

    @Override
    public void checkRequest(PolyMallCommonRequest request) throws PolyMallException {
        PolyMp polyMp = shopConfig.getPoly();
        // 如果只有一个仓库就很简单,根据传过来的key和token做比较即可
        if (null == request.getAppkey() || !StringUtils.equals(polyMp.getAppKey(), request.getAppkey())) {
            throw new PolyMallException(PolyErrorCodeEnum.APPKEY_ERROR.getCode(), PolyErrorCodeEnum.APPKEY_ERROR.getDesc());
        }
        if (null == request.getToken() || !StringUtils.equals(polyMp.getToken(), request.getToken())) {
            throw new PolyMallException(PolyErrorCodeEnum.TOKEN_ERROR.getCode(), PolyErrorCodeEnum.TOKEN_ERROR.getDesc());
        }
        if (StringUtils.isBlank(request.getSign())) {
            throw new PolyMallException(PolyErrorCodeEnum.SIGN_EMPTY.getCode(), PolyErrorCodeEnum.SIGN_EMPTY.getDesc());
        }
        if (StringUtils.isBlank(request.getBizcontent())) {
            throw new PolyMallException(PolyErrorCodeEnum.PARAMS_ERROR.getCode(), PolyErrorCodeEnum.PARAMS_ERROR.getDesc());
        }
        if (StringUtils.isBlank(request.getMethod())) {
            throw new PolyMallException(PolyErrorCodeEnum.METHOD_EMPTY.getCode(), PolyErrorCodeEnum.METHOD_EMPTY.getDesc());
        }
        if (!PolyMallConstants.supportedMethodList.contains(request.getMethod())) {
            throw new PolyMallException(PolyErrorCodeEnum.METHOD_ERROR.getCode(), PolyErrorCodeEnum.METHOD_ERROR.getDesc());
        }
        if (StringUtils.isBlank(request.getSign())) {
            throw new PolyMallException(PolyErrorCodeEnum.SIGN_EMPTY.getCode(), PolyErrorCodeEnum.SIGN_EMPTY.getDesc());
        }
        request.setAppSecret(polyMp.getAppSecret());
    }

    @Override
    public void checkSign(PolyMallCommonRequest request) throws PolyMallException {
        Map<String, String> map = new HashMap<>(4);
        map.put(PolyConstants.DeclaredField.APPKEY, request.getAppkey());
        map.put(PolyConstants.DeclaredField.TOKEN, request.getToken());
        map.put(PolyConstants.DeclaredField.METHOD, request.getMethod());
        map.put(PolyConstants.DeclaredField.BIZCONTENT, request.getBizcontent());

        List<Map.Entry<String, String>> list = new ArrayList<>(map.entrySet());
        list.sort(Comparator.comparing(Map.Entry::getKey));
        Iterator<Map.Entry<String, String>> iterator = list.stream().collect(Collectors.toMap(
                Map.Entry::getKey,
                Map.Entry::getValue,
                (oldValue, newValue) -> oldValue,
                LinkedHashMap::new
        )).entrySet().iterator();

        StringBuilder signString = new StringBuilder();
        while (iterator.hasNext()) {
            Map.Entry<String, String> entry = iterator.next();
            signString.append(entry.getKey()).append(entry.getValue());
        }
        signString.insert(0, request.getAppSecret());
        signString.append(request.getAppSecret());

        String localSign = DigestUtils.md5Hex(signString.toString().toLowerCase());

        if (!request.getSign().equals(localSign)) {
            throw new PolyMallException(PolyErrorCodeEnum.SIGN_ERROR.getCode(), PolyErrorCodeEnum.SIGN_ERROR.getDesc());
        }
    }

    @Override
    public void checkRequestAndSign(PolyMallCommonRequest request) throws PolyMallException {
        log.info("[PolyMall]菠萝派请求：{}", JSONObject.toJSONString(request));
        this.checkRequest(request);
        this.checkSign(request);
    }
    @Override
    public String generateSign(PolyMallCommonGetOrderTraceRequest request) throws PolyMallException {
        //log.info("[PolyMall]菠萝派请求：{}", JSONObject.toJSONString(request));

        // 创建一个Map对象
        Map<String, String> map = new HashMap<>(4);
        map.put(PolyConstants.DeclaredField.APPKEY, request.getAppkey());
        map.put(PolyConstants.DeclaredField.TOKEN, request.getToken());
        map.put(PolyConstants.DeclaredField.METHOD, request.getMethod());
        map.put(PolyConstants.DeclaredField.BIZCONTENT, request.getBizcontent());
        // 将Map转换为List集合
        List<Map.Entry<String, String>> list = new ArrayList<>(map.entrySet());
        // 对List集合进行排序
        list.sort(Comparator.comparing(Map.Entry::getKey));
        // 将排好序的List集合转换回Map
        Iterator<Map.Entry<String, String>> iterator = list.stream().collect(Collectors.toMap(
                Map.Entry::getKey,
                Map.Entry::getValue,
                (oldValue, newValue) -> oldValue,
                LinkedHashMap::new
        )).entrySet().iterator();
        StringBuilder acquireSign = new StringBuilder();
        while (iterator.hasNext()) {
            Map.Entry<String, String> entry = iterator.next();

            acquireSign.append(entry.getKey()).append(entry.getValue());
        }
        acquireSign.insert(0, request.getAppSecret());//替换自己的Secret
        acquireSign.append(request.getAppSecret());//替换自己的Secret
        // 本地生成的签名
       return DigestUtils.md5Hex(acquireSign.toString().toLowerCase());
    }
    //本地签名生成工具
    public static void main(String[] args) {
        //{"appKey":"","appSecret":"","token":""}
        //{"appKey":"8085dbc11647487ea3d9425f9102eb1c","appSecret":"19937fa37061424f9cac5b2247d646d1","token":"e58e4ca0b879404c8e19dd2a7367ad89"}
        PolyMallCommonRequest request = PolyMallCommonRequest.builder()
                .appkey("cbfb89a392134643bbd39fd9ef358165") //替换自己的key
                .token("6cd7a00852db44568dc13373a785cb82") //替换自己的token
                .method("Differ.JH.Business.DownloadProduct") //调用的方法
               .bizcontent("{\"ProductId\":\"\",\"ProductName\":\"\",\"Status\":\"JH_01\",\"PageIndex\":\"1\",\"PageSize\":\"10\"}") //把接口测试工具的入参json贴过来
                //.bizcontent("{\"PageIndex\":\"\",\"PageSize\":\"\",\"WareHouseCode\":\"\"}") //把接口测试工具的入参json贴过来
                .build();
        // 创建一个Map对象
        Map<String, String> map = new HashMap<>(4);
        map.put(PolyConstants.DeclaredField.APPKEY, request.getAppkey());
        map.put(PolyConstants.DeclaredField.TOKEN, request.getToken());
        map.put(PolyConstants.DeclaredField.METHOD, request.getMethod());
        map.put(PolyConstants.DeclaredField.BIZCONTENT, request.getBizcontent());
        // 将Map转换为List集合
        List<Map.Entry<String, String>> list = new ArrayList<>(map.entrySet());
        // 对List集合进行排序
        list.sort(Comparator.comparing(Map.Entry::getKey));
        // 将排好序的List集合转换回Map
        Iterator<Map.Entry<String, String>> iterator = list.stream().collect(Collectors.toMap(
                Map.Entry::getKey,
                Map.Entry::getValue,
                (oldValue, newValue) -> oldValue,
                LinkedHashMap::new
        )).entrySet().iterator();
        StringBuilder acquireSign = new StringBuilder();
        while (iterator.hasNext()) {
            Map.Entry<String, String> entry = iterator.next();

            acquireSign.append(entry.getKey()).append(entry.getValue());
        }
        acquireSign.insert(0, "551d83b520e942639317e6545d7ff2ee");//替换自己的Secret
        acquireSign.append("551d83b520e942639317e6545d7ff2ee");//替换自己的Secret
        // 本地生成的签名
        System.out.println("————————————————————————————————————————————————");
        String localSign = DigestUtils.md5Hex(acquireSign.toString().toLowerCase());
        System.out.println(localSign);
        System.out.println("————————————————————————————————————————————————");
    }

}
